package com.translate.web.service.impl;

import com.translate.web.config.contract.IOSSConfig;
import com.translate.web.dao.OrderMapper;
import com.translate.web.param.contract.IDateRangeParam;
import com.translate.web.param.contract.IIdAndUserIdParam;
import com.translate.web.param.contract.IOrderApplyParam;
import com.translate.web.param.contract.IOrderCommentParam;
import com.translate.web.param.contract.IOrderSearchByTeamParam;
import com.translate.web.param.contract.IPayBehaviorRequestParam;
import com.translate.entity.Order;
import com.translate.vo.contract.IOrderVO;
import com.translate.web.service.IOrderService;
import com.common.util.FieldUtil;
import com.dao.base.IBaseMapper;
import com.page.PageResponseData;
import com.param.contract.IPage;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
public class OrderServiceImpl extends BaseTranslateServiceImpl<Order> implements IOrderService {

	private IOSSConfig config;

	public OrderServiceImpl(OrderMapper mapper) {
		super(mapper);
	}

	protected void insertPropteris(Order data) {
		long time = System.currentTimeMillis() / 1000;
		data.setCreateTime(time);
	}

	protected void updatePropteris(Order data) {

	}

	protected Class<Order> getEntityClass() {
		return Order.class;
	}
	
	public <S extends IPage, VO> PageResponseData<VO> getDataByListBySearch(S marketSearchParam,
			Class<VO> targetClass) {

		PageResponseData<Order> pageResponseData = this.getDataByListBySearch(marketSearchParam);

		long total = pageResponseData.getTotal();

		if (0 == total) {
			return new PageResponseData<>();
		}

		return new PageResponseData<VO>(total, entityConvertToVo(pageResponseData.getData(), targetClass),
				pageResponseData.getPageSize());
	}
	
	@Override
	public <S extends IPage> PageResponseData<Order> getDataByListBySearch(S marketSearchParam) {


		IBaseMapper<Order> baseMapper = this.getBaseMapper();

		int count = baseMapper.getCountBySearch(marketSearchParam);

		if (0 == count) {
			return new PageResponseData<>(0, new ArrayList<>(0));
		}

		List<Order> list = baseMapper.getDataByListBySearch(marketSearchParam);

		duplicateRemoval(list);

		return new PageResponseData<>(count, list, marketSearchParam.getSelectCount());
	}
	

	protected <S extends IPage> String sqlByGetCounttAfterProcesser(S param) {

		IDateRangeParam userIdParam = (IDateRangeParam) param;

		return this.sqlByGetCount("user_id = " + userIdParam.getUserId() + " and `status` = 0");
	}

	protected <S extends IPage> String sqlByGetPageListAfterProcesser(S param) {

		IDateRangeParam userIdParam = (IDateRangeParam) param;

		return this.sqlByGetPageList(" and user_id = " + userIdParam.getUserId() + " and `status` = 0" +" order by create_time desc");
	}

	@Override
	protected Order getEntityInstance() {
		// TODO Auto-generated method stub
		return new Order();
	}

	@Override
	protected String getAssocKey() {
		return "pay_manager_id";
	}

	@Override
	public List<Order> getOrdersByIds(long[] ids, int serviceType) {

		OrderMapper mapper = this.getBaseMapper();

		return mapper.getOrdersByIds(ids, serviceType);
	}

	@Override
	@Transactional(propagation = Propagation.MANDATORY)
	public int cancelOrder(int managerId, int userId) {

		OrderMapper mapper = this.getBaseMapper();

		return mapper.cancelOrder(managerId, userId);
	}

	@Override
	@Transactional(propagation = Propagation.MANDATORY)
	public int paySuccess(IPayBehaviorRequestParam behaviorRequestParam) {

		OrderMapper mapper = this.getBaseMapper();

		return mapper.paySuccess(behaviorRequestParam);
	}

	@Override
	public List<Order> getOrdersByUserIdAndManagerId(IPayBehaviorRequestParam behaviorRequestParam) {
		return ((OrderMapper) this.getBaseMapper()).getOrdersByUserIdAndManagerId(behaviorRequestParam);
	}

	@Override
	@Transactional(propagation = Propagation.MANDATORY)
	public int toBeConfirmed(IPayBehaviorRequestParam behaviorRequestParam) {

		OrderMapper mapper = this.getBaseMapper();

		return mapper.toBeConfirmed(behaviorRequestParam);
	}

	static String[] columns = new String[] { "user_id", "team_id", };

	@Override
	public <VO extends IOrderVO> PageResponseData<VO> getOrdersByUseRecharge(IDateRangeParam dateRangeParam,
			Class<VO> target, byte isRegimental, long teamId) {
		OrderMapper mapper = this.getBaseMapper();

		long[] values = new long[] { dateRangeParam.getUserId(), teamId, };

		Long startTime = dateRangeParam.getStartTime();
		Long endTime = dateRangeParam.getEndTime();

		int countByRechargeSearch = mapper.getCountByRechargeSearch(columns[isRegimental], values[isRegimental],
				startTime, endTime);

		if (0 == countByRechargeSearch) {
			return new PageResponseData<VO>();
		}

		IPage iPage = (IPage)dateRangeParam;
		List<Order> list = mapper.getDataByListByRechargeSearch(
				columns[isRegimental], values[isRegimental], startTime,
				endTime,
				iPage.getLastId(), iPage.getSelectCount());

		List<VO> entityConvertToVo = entityConvertToVo(list, target);

		return new PageResponseData<VO>(countByRechargeSearch, entityConvertToVo);
	}

	@Resource
	public void setRedisTemplate(RedisTemplate<String, ? extends Object> redisTemplate) {
		this.redisTemplate = redisTemplate;
	}

	/**
	 * 取消单个订单
	 */
	@Override
	@Transactional(propagation = Propagation.MANDATORY)
	public int cancelOrder(IIdAndUserIdParam param) {

		OrderMapper mapper = this.getBaseMapper();

		return mapper.cancelOrderSingle(param);
	}

	@Override
	public int commentOrder(IOrderCommentParam param) {
		OrderMapper mapper = this.getBaseMapper();

		param.setTime((int) (System.currentTimeMillis() / 1000));

		return mapper.commentOrder(param);
	}

	@Override
	@Transactional(propagation = Propagation.MANDATORY)
	public <P extends IIdAndUserIdParam> int updateService(P parameter) {
		OrderMapper mapper = this.getBaseMapper();

		return mapper.updateService(parameter);
	}

	@Override
	public <P extends IIdAndUserIdParam> int cancelSecondaryService(P parameter, Order dataDetail) {
		OrderMapper mapper = this.getBaseMapper();

		Boolean commentStatus = dataDetail.getCommentStatus();

		int userStatus = 8, orderStatus = 11; // 已完成

		if (false == commentStatus) {
			userStatus = 5;

			orderStatus = 10; // 已确认
		}

		return mapper.cancelSecondaryService((int) parameter.getUserId(), parameter.getId(), userStatus, orderStatus);
	}

	@Override
	public <VO extends IOrderVO> PageResponseData<VO> getOrderListByTeam(IOrderSearchByTeamParam searchByTeamParam,
			Class<VO> target) {

		OrderMapper mapper = this.getBaseMapper();

		int countByTeam = mapper.countByTeam(searchByTeamParam);

		if (0 == countByTeam) {
			return new PageResponseData<VO>();
		}

		List<Order> list = mapper.getDataListByTeam(searchByTeamParam);

		List<VO> entityConvertToVo = entityConvertToVo(list, target);

		return new PageResponseData<VO>(countByTeam, entityConvertToVo);

	}

	@Override
	public int applicationForReimbursementContract(IOrderApplyParam orderApplyParam) {
		Integer id = orderApplyParam.getId();

		Order order = new Order();

		order.setId(id);

		order.setUserId(orderApplyParam.getUserId());

		order.setNeedContract((byte) 1);

		OrderMapper baseMapper = this.getBaseMapper();

		return baseMapper.applicationForReimbursementContract(order);
	}

	@Override
	public int needTranslationProof(IOrderApplyParam orderApplyParam) {
		Integer id = orderApplyParam.getId();

		Order selectByPrimaryKey = this.selectByPrimaryKey(id);

		if (null == selectByPrimaryKey) {
			return -1;
		}

		Byte havaTranslationProof = selectByPrimaryKey.getHavaTranslationProof();
		if (null != havaTranslationProof && havaTranslationProof != 1) {
			return -2;
		}

		Order order = new Order();

		order.setId(id);

		order.setUserId(orderApplyParam.getUserId());

		OrderMapper baseMapper = this.getBaseMapper();

		return baseMapper.needTranslationProof(order);
	}

	@Override
	public int deleteByIdAndUserId(IIdAndUserIdParam param) {
		// TODO Auto-generated method stub
		OrderMapper baseMapper = this.getBaseMapper();

		return baseMapper.deleteByIdAndUserId(param.getId(), (int) param.getUserId());
	}

	@Override
	@Transactional(propagation = Propagation.MANDATORY)
	public int setPayManagerByOrderData(IPayBehaviorRequestParam behaviorRequestParam, int payManagerId) {

		OrderMapper baseMapper = this.getBaseMapper();

		return baseMapper.setPayManagerByOrderData(behaviorRequestParam.getId(), (int) behaviorRequestParam.getUserId(),
				payManagerId);
	}

	public <VO> VO getDataByIdFromCache(IIdAndUserIdParam param, Class<VO> type, String key, int time) {

		IOrderVO dataByIdFromCache = (IOrderVO) super.getDataByIdFromCache(param, type, key, time);

		if (null == dataByIdFromCache) {
			return (VO) dataByIdFromCache;
		}

		String translationProofFile = dataByIdFromCache.getTranslationProofFile();

		String url = config.getURL();

		if (null != translationProofFile && 0 != translationProofFile.length()) {
			dataByIdFromCache.setTranslationProofFile(url.concat("/").concat(translationProofFile));
		}

		String contractFile = dataByIdFromCache.getContractFile();

		if (null != contractFile && 0 != contractFile.length()) {
			dataByIdFromCache.setContractFile(url.concat("/").concat(contractFile));
		}

		return (VO) dataByIdFromCache;
	}

	@Resource
	public void setConfig(IOSSConfig config) {
		this.config = config;
	}

	@Override
	public List<Order> getAlreadyPaymentByBalance(int managerId, int userId) {

		OrderMapper baseMapper = this.getBaseMapper();

		return baseMapper.getAlreadyPaymentByBalance(managerId, userId);
	}

	@Override
	public int cancelOrderByTeam(Integer id, int teamId) {
		OrderMapper baseMapper = this.getBaseMapper();
		return baseMapper.cancelOrderByTeam(id, teamId);
	}


	@Override
	public List<Order> getOrdersByPayManagerIdAndUserId(int payManagerId, int userId) {
		OrderMapper baseMapper = this.getBaseMapper();
		return baseMapper.getOrdersByPayManagerIdAndUserId(payManagerId, userId);
	}

	@Override
	public List<Order> getOrdersByPayManagerIdAndPayType(int payManagerId, int userId) {
		OrderMapper baseMapper = this.getBaseMapper();
		return baseMapper.getOrdersByPayManagerIdAndPayType(payManagerId, userId);
	}

	@Override
	public List<Order> getOrdersByPayManagerIdAndTeamId(int payManagerId, int teamId) {
		OrderMapper baseMapper = this.getBaseMapper();
		return baseMapper.getOrdersByPayManagerIdAndTeamId(payManagerId, teamId);
	}

	@Override
	public int paySuccessByTeam(IPayBehaviorRequestParam behaviorRequestParam) {
		OrderMapper baseMapper = this.getBaseMapper();
		return baseMapper.paySuccessByTeam(behaviorRequestParam);
	}

	@Override
	public int toBeConfirmedByTeam(IPayBehaviorRequestParam behaviorRequestParam) {
		// TODO Auto-generated method stub
		OrderMapper baseMapper = this.getBaseMapper();

		return baseMapper.toBeConfirmedByTeam(behaviorRequestParam);
	}

	@Override
	public boolean isCancelledByPayManager(long userId, long payMangerId) {
		
		List<Order> ordersByPayManagerIdAndUserId = this.getOrdersByPayManagerIdAndUserId((int)payMangerId, (int)userId);
		
		int size = ordersByPayManagerIdAndUserId.size();
		if (0 == size) {
			return false;
		}
		
		int cancelNum = 0; 
		
		for (Order order : ordersByPayManagerIdAndUserId) {
			
			if (-1 == order.getOrderStatus()) {
                cancelNum++;
            }
		}
		
		return cancelNum == size;
	}
}